//
//  VideoRecordView.m
//  AnotherMediaTool
//
//  Created by fh on 2018/9/10.
//  Copyright © 2018年 fh. All rights reserved.
//

#import "VideoRecordView.h"
#import <AVFoundation/AVFoundation.h>

@interface VideoRecordView () <UIGestureRecognizerDelegate> {
    int _flashModeCycle;
    BOOL _recording;
}
/*** 记录开始的缩放比例 */
@property (nonatomic, assign) CGFloat beginGestureScale;
/*** 最后的缩放比例 */
@property (nonatomic, assign) CGFloat effectiveScale;
/** 预览图父视图 */
@property (nonatomic, strong) UIView *previewBackgroundView;
/** 底部菜单栏 */
@property (nonatomic, strong) UIView *bottomMenuView;
/** 顶部菜单栏 */
@property (nonatomic, strong) UIView *topMenuView;
/** 返回按钮 */
@property (nonatomic, strong) UIButton *backButton;
/** 录制按钮 */
@property (nonatomic, strong) CaptureButton *videoRecordButton;
/** 前后摄像头切换按钮 */
@property (nonatomic, strong) UIButton *toggleButton;
/** 闪光灯按钮 */
@property (nonatomic, strong) UIButton *flashButton;
/** 聚焦光标 */
@property (nonatomic, strong) UIImageView *focusCursor;

/** 确定按钮 */
@property (nonatomic, strong) UIButton *sureButton;
/** 取消按钮 */
@property (nonatomic, strong) UIButton *cancleButton;
/** 视频预览播放进度条 */
@property (nonatomic, strong) UIProgressView *videoPreviewProgress;

/** 视频预览播放器对象 */
@property (nonatomic, strong) AVPlayer *player;
/** 视频预览播放器层 */
@property (nonatomic, strong) AVPlayerLayer *playerLayer;
/** 视频预览播放链接 */
@property (nonatomic, copy) NSURL *videoUrl;
/** 播放进度事件观察者 */
@property (nonatomic, strong) id playerPeriodicTimeObserver;

/** 临时内部视频截图 */
@property (nonatomic, strong) UIImage *tempVideoImage;
@end

@implementation VideoRecordView
- (void)dealloc {
    [self removeAvPlayerNotification];
    [self stopPlayer];
    self.player = nil;
}
- (instancetype)init {
    if (self = [super init]) {
        
        _effectiveScale = 1.0;
        _beginGestureScale = 1.0; // 1
        
        _minScaleAndCropFactor = 1.0;
        _maxScaleAndCropFactor = 4.0;
        
        _flashModeCycle = 0;
        _recording = NO;
        
        [self addSubview:self.previewBackgroundView];
        [self addSubview:self.topMenuView];
        [self addSubview:self.bottomMenuView];
        
        [self.previewBackgroundView addSubview:self.preview];
        [self.previewBackgroundView addSubview:self.focusCursor];
        
        [self.topMenuView addSubview:self.flashButton];
        [self.topMenuView addSubview:self.recordTimeLabel];
        [self.topMenuView addSubview:self.videoPreviewProgress];
        
        [self.bottomMenuView addSubview:self.videoRecordButton];
        [self.bottomMenuView addSubview:self.backButton];
        [self.bottomMenuView addSubview:self.toggleButton];
        
        [self.bottomMenuView addSubview:self.sureButton];
        [self.bottomMenuView addSubview:self.cancleButton];
        
        [self.previewBackgroundView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self);
        }];
        [self.topMenuView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.left.top.right.equalTo(@(0));
            make.height.equalTo(@(kkScreenHeight * 0.06));
        }];
        [self.bottomMenuView mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.left.right.bottom.equalTo(@(0));
            make.height.equalTo(@(kkScreenHeight * 0.18));
        }];
        
        [self.preview mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.edges.equalTo(self.previewBackgroundView);
        }];
        [self.focusCursor mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.height.width.equalTo(@(75));
            make.center.equalTo(self.previewBackgroundView);
        }];
        
        [self.flashButton mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(@(20));
            make.top.bottom.equalTo(@(0));
            make.width.equalTo(self.flashButton.mas_height);
        }];
        [self.recordTimeLabel mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.centerX.equalTo(self.topMenuView.mas_centerX);
            make.centerY.equalTo(self.topMenuView.mas_centerY);
        }];
        [self.videoPreviewProgress mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.height.equalTo(@(1));
            make.left.right.bottom.equalTo(@(0));
        }];
        
        [self.videoRecordButton mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.bottom.equalTo(@(-15));
            make.centerX.equalTo(self.bottomMenuView.mas_centerX);
            make.width.height.equalTo(@(70));
        }];
        [self.backButton mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.centerY.equalTo(self.videoRecordButton.mas_centerY);
            make.left.equalTo(@(20));
            make.width.height.equalTo(@(50));
        }];
        [self.toggleButton mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.centerY.equalTo(self.videoRecordButton.mas_centerY);
            make.right.equalTo(@(-20));
            make.width.height.equalTo(@(50));
        }];
        
        [self.cancleButton mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.centerY.equalTo(self.videoRecordButton.mas_centerY);
            make.left.equalTo(@(20));
            make.height.equalTo(@(45));
            make.width.equalTo(@(80));
        }];
        [self.sureButton mas_remakeConstraints:^(MASConstraintMaker *make) {
            make.centerY.equalTo(self.videoRecordButton.mas_centerY);
            make.right.equalTo(@(-20));
            make.height.equalTo(@(45));
            make.width.equalTo(@(80));
        }];
    }
    return self;
}
#pragma mark - Public
- (void)configuratePrepareView {
    self.recordTimeLabel.text = @"00:00:00";
    self.bottomMenuView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.3];
    self.backButton.hidden = NO;
    self.toggleButton.hidden = NO;
    self.flashButton.hidden = NO;
    self.videoRecordButton.hidden = NO;
    self.sureButton.hidden = YES;
    self.cancleButton.hidden = YES;
    self.focusCursor.hidden = NO;
    self.videoPreviewProgress.hidden = YES;
    
    [self stopPlayer];
}
- (void)configurateRecordingView {
    self.bottomMenuView.backgroundColor = [UIColor clearColor];
    self.backButton.hidden = YES;
    self.toggleButton.hidden = YES;
    self.flashButton.hidden = YES;
    self.videoRecordButton.hidden = NO;
    self.sureButton.hidden = YES;
    self.cancleButton.hidden = YES;
    self.focusCursor.hidden = NO;
    self.videoPreviewProgress.hidden = YES;
    
    [self stopPlayer];
}
- (void)configurateVideoPreview {
    self.bottomMenuView.backgroundColor = [UIColor clearColor];
    self.backButton.hidden = YES;
    self.toggleButton.hidden = YES;
    self.flashButton.hidden = YES;
    self.videoRecordButton.hidden = YES;
    self.sureButton.hidden = NO;
    self.cancleButton.hidden = NO;
    self.focusCursor.hidden = YES;
    self.videoPreviewProgress.hidden = NO;
}
- (void)previewVideoWithVideoURL:(NSURL *)videoURL videoImage:(UIImage *)videoImage videoDuration:(int)videoDuration videoSize:(float)videoSize {
    self.tempVideoImage = videoImage;
    // 创建播放器层
    AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:self.player];
    playerLayer.frame = self.bounds;
    [self.previewBackgroundView.layer addSublayer:playerLayer];
    self.playerLayer = playerLayer;
    
    if (videoURL) {
        self.videoUrl = videoURL;
    }
    [self updateVideoRecordTimeStrWithVideoProcessTime:videoDuration];
    [self configurateVideoPreview];
}
#pragma mark - Notification
- (void)playbackFinished:(NSNotification *)notification {
    [self.player seekToTime:CMTimeMake(0, 1)];
    [self.player play];
}

#pragma mark - Event
- (void)videoRecordButtonAction:(CaptureButton *)button {
    WeakSelf;
    BaseWeak(button, weakButton);
    button.animationResultBlock = ^(BOOL isSelected) {
        if (isSelected) {
            [weakSelf configurateRecordingView];
        }else {
            [weakSelf configuratePrepareView];
        }
        if (weakSelf.videoRecordButtonClickedBlock) {
            weakSelf.videoRecordButtonClickedBlock(isSelected,weakButton);
        }
    };
    _recording = !_recording;
    if (_recording) {
        button.selected = YES;
    }else {
        button.selected = NO;
    }
}
- (void)backButtonAction:(UIButton *)button {
    if (self.backButtonClickedBlock) {
        self.backButtonClickedBlock(button);
    }
}
- (void)toggleButtonAction:(UIButton *)button {
    if (self.toggleButtonClickedBlock) {
        self.toggleButtonClickedBlock(button);
    }
}
- (void)flashButtonAction:(UIButton *)button {
    
    VideoRecordViewFlashMode mode = VideoRecordViewFlashModeOff;
    int value = (++_flashModeCycle)%3;
    switch (value) {
        case 0:
            [_flashButton setImage:[[UIImage imageNamed:@"camera_flash_off"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal];
            mode = VideoRecordViewFlashModeOff;
            break;
        case 1:
            [_flashButton setImage:[[UIImage imageNamed:@"camera_flash_on"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal];
            mode = VideoRecordViewFlashModeOn;
            break;
        case 2:
            [_flashButton setImage:[[UIImage imageNamed:@"camera_flash_auto"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal];
            mode = VideoRecordViewFlashModeAuto;
            break;
        default:
            break;
    }
    
    if (self.flashButtonClickedBlock) {
        self.flashButtonClickedBlock(button,mode);
    }
}

- (void)focusPreviewAction:(UITapGestureRecognizer *)tapGestureRecognizer {
    
    CGPoint point = [tapGestureRecognizer locationInView:self.previewBackgroundView];
    
    self.focusCursor.center = point;
    self.focusCursor.transform = CGAffineTransformMakeScale(1.25, 1.25);
    self.focusCursor.alpha = 1.0;
    WeakSelf;
    [UIView animateWithDuration:0.6 animations:^{
        weakSelf.focusCursor.transform = CGAffineTransformIdentity;
    } completion:^(BOOL finished) {
        weakSelf.focusCursor.alpha = 0;
    }];
    
    if (self.focusPreviewClickedBlock) {
        self.focusPreviewClickedBlock(tapGestureRecognizer,point);
    }
}

- (void)pinchGestureRecognizerAction:(UIPinchGestureRecognizer *)recognizer {
    
    BOOL allTouchesAreOnThePreviewLayer = YES;
    NSUInteger numTouches = [recognizer numberOfTouches], i;
    for ( i = 0; i < numTouches; ++i ) {
        CGPoint location = [recognizer locationOfTouch:i inView:self.preview];
        CGPoint convertedLocation = [self.preview.layer convertPoint:location fromLayer:self.preview.layer.superlayer];
        if ( ! [self.preview.layer containsPoint:convertedLocation] ) {
            allTouchesAreOnThePreviewLayer = NO;
            break;
        }
    }
    if (allTouchesAreOnThePreviewLayer) {
        self.effectiveScale = self.beginGestureScale * recognizer.scale;
        
        if (self.effectiveScale < self.minScaleAndCropFactor){
            self.effectiveScale = self.minScaleAndCropFactor;
        }
        if (self.effectiveScale > self.maxScaleAndCropFactor) {
            self.effectiveScale = self.maxScaleAndCropFactor;
        }
        CGFloat value = (self.effectiveScale - self.minScaleAndCropFactor)/(self.maxScaleAndCropFactor - self.minScaleAndCropFactor);
        if (self.deviceZoomBlock) {
            self.deviceZoomBlock(value);
        }
    }
}

- (void)sliderValueChangeAction:(UISlider *)sender {
    sender.alpha = 1;
    CGFloat value = sender.value * (self.maxScaleAndCropFactor - self.minScaleAndCropFactor) + self.minScaleAndCropFactor;
    if (value < self.minScaleAndCropFactor) {
        value = self.minScaleAndCropFactor;
    }
    if (value > self.maxScaleAndCropFactor) {
        value = self.maxScaleAndCropFactor;
    }
    self.effectiveScale = value * (self.maxScaleAndCropFactor - self.minScaleAndCropFactor) + self.minScaleAndCropFactor;
    if (self.deviceZoomBlock) {
        self.deviceZoomBlock(sender.value);
    }
}

- (void)sureButtonAction:(UIButton *)button {
    [self configuratePrepareView];
    if (self.sureButtonClickedBlock) {
        self.sureButtonClickedBlock(button,self.videoUrl,self.tempVideoImage);
    }
}
- (void)cancleButtonAction:(UIButton *)button {
    [self configuratePrepareView];
    if (self.cancleButtonClickedBlock) {
        self.cancleButtonClickedBlock(button);
    }
}
#pragma mark - Private
- (void)addAVPlayerNotification:(AVPlayerItem *)playerItem {
    if (!playerItem) {
        return;
    }
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object:self.player.currentItem];
    __weak typeof(self) weakSelf = self;
    // 观察播放进度: 30帧
    _playerPeriodicTimeObserver = [self.player addPeriodicTimeObserverForInterval:CMTimeMake(1, 30.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
        double duration = (double)playerItem.duration.value/playerItem.duration.timescale;
        double currentPlayTime = (double)time.value/time.timescale;
        if (currentPlayTime == 0) {
            [weakSelf.videoPreviewProgress setProgress:currentPlayTime/duration animated:NO];
        }else {
            [weakSelf.videoPreviewProgress setProgress:currentPlayTime/duration animated:YES];
        }
#ifdef DEBUG
//        float currentPlayTime = (double)playerItem.currentTime.value/ playerItem.currentTime.timescale;
//        NSLog(@"\n当前播放时间: %f\n视频总长: %f\n",currentPlayTime,duration);
#endif
    }];
}

- (void)removeAvPlayerNotification {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [self.player removeTimeObserver:_playerPeriodicTimeObserver];
    _playerPeriodicTimeObserver = nil;
}

- (void)stopPlayer {
    // 如果在播放状态就停止
    if (self.player.rate == 1) {
        [self.player pause];
    }
    [self.playerLayer removeFromSuperlayer];
    self.playerLayer = nil;
}

- (void)nextPlayer {
    [self.player seekToTime:CMTimeMakeWithSeconds(0, _player.currentItem.duration.timescale)];
    [self.player replaceCurrentItemWithPlayerItem:[self getAVPlayerItem]];
    [self addAVPlayerNotification:self.player.currentItem];
    if (self.player.rate == 0) {
        [self.player play];
    }
}

- (AVPlayerItem *)getAVPlayerItem {
    AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:self.videoUrl];
    return playerItem;
}

// 更新录制时间
- (void)updateVideoRecordTimeStrWithVideoProcessTime:(float)processTime {
    NSInteger houri = (NSInteger)processTime / 60 / 60;
    NSInteger mini = (NSInteger)processTime / 60;
    NSInteger seci = (NSInteger)processTime % 60;
    self.recordTimeLabel.text = [NSString stringWithFormat:@"%.2ld:%.2ld:%.2ld",houri, mini,seci];
}
#pragma mark - UIGestureRecognizerDelegate
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if ( [gestureRecognizer isKindOfClass:[UIPinchGestureRecognizer class]] ) {
        self.beginGestureScale = self.effectiveScale;
    }
    return YES;
}
#pragma mark - Setter and getter
- (void)setMinScaleAndCropFactor:(CGFloat)minScaleAndCropFactor {
    _minScaleAndCropFactor = minScaleAndCropFactor;
    self.beginGestureScale = minScaleAndCropFactor;
    self.effectiveScale = minScaleAndCropFactor;
}
- (void)setVideoUrl:(NSURL *)videoUrl {
    _videoUrl = videoUrl;
    [self removeAvPlayerNotification];
    [self nextPlayer];
}
- (AVPlayer *)player {
    if (!_player) {
        _player = [AVPlayer playerWithPlayerItem:[self getAVPlayerItem]];
        [self addAVPlayerNotification:_player.currentItem];
    }
    return _player;
}
- (CaptureButton *)videoRecordButton {
    if (!_videoRecordButton) {
        _videoRecordButton = [CaptureButton buttonWithType:UIButtonTypeCustom];
        _videoRecordButton.isVideoCamera = YES;
        [_videoRecordButton addTarget:self action:@selector(videoRecordButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _videoRecordButton;
}
- (UIView *)previewBackgroundView {
    if (!_previewBackgroundView) {
        _previewBackgroundView = [UIView new];
        _previewBackgroundView.clipsToBounds = YES;
        _previewBackgroundView.backgroundColor = UIColorFromHex(0xffb650);
        UITapGestureRecognizer *focusGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(focusPreviewAction:)];
        [_previewBackgroundView addGestureRecognizer:focusGesture];
    }
    return _previewBackgroundView;
}
- (UIView *)preview {
    if (!_preview) {
        _preview = [UIView new];
        _preview.backgroundColor = UIColorFromHex(0xff9a7a);
        UIPinchGestureRecognizer *pinTapGesture = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchGestureRecognizerAction:)];
        pinTapGesture.delegate = self;
        [_preview addGestureRecognizer:pinTapGesture];
    }
    return _preview;
}
- (UIView *)topMenuView {
    if (!_topMenuView) {
        _topMenuView = [UIView new];
        _topMenuView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.3];
    }
    return _topMenuView;
}
- (UIView *)bottomMenuView {
    if (!_bottomMenuView) {
        _bottomMenuView = [UIView new];
        _bottomMenuView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.3];
    }
    return _bottomMenuView;
}
- (UILabel *)recordTimeLabel {
    if (!_recordTimeLabel) {
        _recordTimeLabel = [UILabel new];
        _recordTimeLabel.font = [UIFont boldSystemFontOfSize:20];
        _recordTimeLabel.textColor = [UIColor whiteColor];
        _recordTimeLabel.textAlignment = NSTextAlignmentCenter;
        _recordTimeLabel.text = @"00:00:00";
    }
    return _recordTimeLabel;
}
- (UIButton *)backButton {
    if (!_backButton) {
        _backButton = [UIButton new];
        [_backButton setImage:[[UIImage imageNamed:@"camera_cancle"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal];
        [_backButton addTarget:self action:@selector(backButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _backButton;
}
- (UIButton *)toggleButton {
    if (!_toggleButton) {
        _toggleButton = [UIButton new];
        [_toggleButton setImage:[[UIImage imageNamed:@"camera_toggle"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal];
        [_toggleButton setImageEdgeInsets:UIEdgeInsetsMake(3, 3, 3, 3)];
        [_toggleButton addTarget:self action:@selector(toggleButtonAction:) forControlEvents:UIControlEventTouchUpInside];
    }
    return _toggleButton;
}
- (UIButton *)flashButton {
    if (!_flashButton) {
        _flashButton = [UIButton new];
        _flashButton.titleLabel.font = [UIFont systemFontOfSize:15];
        _flashButton.titleLabel.textAlignment = NSTextAlignmentLeft;
        [_flashButton addTarget:self action:@selector(flashButtonAction:) forControlEvents:UIControlEventTouchUpInside];
        [_flashButton setImage:[[UIImage imageNamed:@"camera_flash_off"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] forState:UIControlStateNormal];
        [_flashButton setImageEdgeInsets:UIEdgeInsetsMake(8, 8, 8, 8)];
    }
    return _flashButton;
}
- (UIImageView *)focusCursor {
    if (!_focusCursor) {
        _focusCursor = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"camera_focus_orange"]];
        _focusCursor.alpha = 0;
    }
    return _focusCursor;
}

- (UIButton *)cancleButton {
    if (!_cancleButton) {
        _cancleButton = [UIButton new];
        [_cancleButton setTitle:@"重拍" forState:UIControlStateNormal];
        [_cancleButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        _cancleButton.titleLabel.font = [UIFont boldSystemFontOfSize:18];
        [_cancleButton addTarget:self action:@selector(cancleButtonAction:) forControlEvents:UIControlEventTouchUpInside];
        _cancleButton.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
        _cancleButton.layer.cornerRadius = 3;
        _cancleButton.hidden = YES;
    }
    return _cancleButton;
}
- (UIButton *)sureButton {
    if (!_sureButton) {
        _sureButton = [UIButton new];
        [_sureButton setTitle:@"选择" forState:UIControlStateNormal];
        [_sureButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
        _sureButton.titleLabel.font = [UIFont boldSystemFontOfSize:18];
        [_sureButton addTarget:self action:@selector(sureButtonAction:) forControlEvents:UIControlEventTouchUpInside];
        _sureButton.backgroundColor = [UIColor colorWithWhite:0 alpha:0.5];
        _sureButton.layer.cornerRadius = 3;
        _sureButton.hidden = YES;
    }
    return _sureButton;
}
- (UIProgressView *)videoPreviewProgress {
    if (!_videoPreviewProgress) {
        _videoPreviewProgress = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleBar];
        _videoPreviewProgress.progressTintColor = UIColorFromHex(0xff9a7a);
        _videoPreviewProgress.trackTintColor = [UIColor whiteColor];
        _videoPreviewProgress.hidden = YES;
    }
    return _videoPreviewProgress;
}
@end
